package com.syqc.videos

import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.view.isVisible
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.syqc.comlib.UserConstant
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.syqc.comlib.utils.GsonUtil
import com.syqc.comlib.utils.MLog
import com.syqc.comlib.utils.ScreenUtil
import com.syqc.entity.RealVideoInfo
import com.syqc.entity.VideoState
import com.syqc.monitor.R
import com.syqc.net.ServiceHelper
import com.syqc.utils.UrlUtil
import com.syqc.utils.VideoHostUtil
import com.syqc.videos.interfaces.IRealPlayerListener
import com.syqc.videos.players.RealPlayer
import io.reactivex.rxjava3.disposables.Disposable
import java.net.URLEncoder
import java.util.*

class RealPlayerAdapter(private val userId: String) :
    BaseQuickAdapter<RealVideoInfo, BaseViewHolder>(R.layout.item_real_player) {
    override fun getItemViewType(position: Int): Int {
        return position
    }

    companion object {
        const val TAG = "RealPlayerAdapter"
    }

    //全屏的Key
    private var fullKey: String = ""

    private var videoHost: String = ""
    var carId: String = ""
        set(value) {
            field = value
            val host = VideoHostUtil.getVideoHost(value)
            videoHost = VideoHostUtil.getHost(host)
        }
    private val userIdEncode = URLEncoder.encode(userId.replace(".", "_"), "utf-8")
    private val user = "$userIdEncode*${UserConstant.current_pwd_md5}"

    val playerMap = HashMap<String, RealPlayer>()

    override fun convert(holder: BaseViewHolder, item: RealVideoInfo) {
        val realPlayer = holder.getView<RealPlayer>(R.id.realPlayer)
        val toast = holder.getView<TextView>(R.id.tvRealToast)
        val flVideo = holder.getView<FrameLayout>(R.id.flVideo)
        val layoutParams = flVideo.layoutParams
        if (data.size > 1) {
            layoutParams.height = ScreenUtil.dp2px(context, 180)
        } else {
            layoutParams.height = ScreenUtil.dp2px(context, 360)
        }
        flVideo.layoutParams = layoutParams
        realPlayer.run {
            showLoadProgress(false)
            playTag = TAG
            playPosition = holder.layoutPosition
            isNeedLockFull = true
            isLockLand = true
            backButton.isVisible = false
            setPass(item.videoPass)
            playerMap[item.videoPass] = realPlayer
            fullscreenButton.setOnClickListener {
                startWindowFullscreen(context, false, true)
            }
            startButton.setOnClickListener {
                if (isInPlayingState) {
                    resetPlayer(item, this@run)
                } else {
                    toast.isVisible = false
                    startPlay(item, this@run)
                }
            }
            setRealListener(object : IRealPlayerListener {
                override fun onStreamChange() {
                    changeStreamOrClose(item, this@run, RealType.SWITCH)
                }
            })
            setVideoAllCallBack(object : GSYSampleCallBack() {
                override fun onQuitFullscreen(url: String?, vararg objects: Any?) {
                    super.onQuitFullscreen(url, *objects)
                    fullKey = ""
                }

                override fun onEnterFullscreen(url: String?, vararg objects: Any?) {
                    super.onEnterFullscreen(url, *objects)
                    currentPlayer.titleTextView.text = objects[0].toString()
                    fullKey = getKey()
                }

                override fun onPlayError(url: String?, vararg objects: Any?) {
                    super.onPlayError(url, *objects)
                    release()
                    startButton.isVisible = false
                    getState(item, this@run, toast)
                }
            })

            if (!isInPlayingState) {
                toast.isVisible = false
                startPlay(item, this@run)
            }
        }

    }

    /**开始播放*/
    private fun startPlay(item: RealVideoInfo, player: RealPlayer) {
        player.setUp(getRealUrl(item, RealType.PLAY), false, item.videoName)
        player.startPlayLogic()
    }

    /**重置播放器*/
    private fun resetPlayer(item: RealVideoInfo, player: RealPlayer) {
        player.release()
        changeStreamOrClose(item, player, RealType.CLOSE)
    }

    /**
     * 根据类型获取视频链接
     *
     * @param item
     * @param type
     * @return
     */
    private fun getRealUrl(item: RealVideoInfo, type: RealType): String {
        return when (type) {
            RealType.PLAY -> {
                item.run {
                    val uuid = UUID.randomUUID().toString()
                    item.uuid = uuid
                    "${videoHost}/httpflv.rplay.$uuid.$user.$carId.$videoPass.0.$videoStream"
                }
            }

            RealType.CLOSE -> "${videoHost}/httpflv.rctr.close.${item.uuid}"
            RealType.SWITCH -> "${videoHost}/httpflv.rctr.switch.${item.uuid}.${if (item.videoStream == "1") "0" else "1"}"
            RealType.STATE -> "${videoHost}/httpflv.state.${item.uuid}"
        }
    }

    /*********************************************************************************************************/
    private val netMap = HashMap<String, Disposable>()

    /**
     * 查询状态
     *
     * @param entity
     * @param toast
     * @param player
     */
    private fun getState(item: RealVideoInfo, player: RealPlayer, toast: TextView) {
        player.showLoadProgress(true)
        val subscribe =
            ServiceHelper.getRepository().getVideoState(getRealUrl(item, RealType.STATE))
                .subscribe({
                    player.showLoadProgress(false)
                    if (it.isNullOrEmpty()) {
                        toast.text = UrlUtil.getToastMap()["88"]
                        toast.isVisible = true
                        return@subscribe
                    }
                    val value = if (!it.endsWith("}")) {
                        "$it}"
                    } else {
                        it
                    }
                    val result = GsonUtil.formObject<VideoState?>(value)

                    if (result == null) {
                        toast.text = UrlUtil.getToastMap()["88"]
                    } else {
                        toast.text = UrlUtil.getToastMap()[result.state]
                    }
                    toast.isVisible = true
                }, {
                    player.showLoadProgress(false)
                    if (it.message == context.getString(R.string.net_error_1006)) {
                        toast.text = UrlUtil.getToastMap()["66"]
                    }
                    toast.isVisible = true
                })
        netMap[item.videoPass] = subscribe
    }

    /**
     * 关闭或这切换码流
     *
     * @param item
     * @param player
     * @param type
     */
    fun changeStreamOrClose(item: RealVideoInfo, player: RealPlayer?, type: RealType) {
        val subscribe =
            ServiceHelper.getRepository().getVideoState(getRealUrl(item, type))
                .subscribe({
                    val result = GsonUtil.formObject<VideoState>(it)
                    if (result.state == "0" && type == RealType.SWITCH) {
                        if (item.videoStream == "1")
                            item.videoStream = "0"
                        else
                            item.videoStream = "1"
                    }
                }, {
                    if (type == RealType.SWITCH) {
                        MLog.e(" 切换码流失败")
                    }
                })
        netMap[item.videoPass] = subscribe
    }

    /**
     * 关闭或这切换码流
     *
     * @param item
     * @param player
     * @param type
     */
    fun changeStreamOrClose(item: RealVideoInfo, player: RealPlayer?, stream: String) {
        player?.changeStreamOut(stream)
        val subscribe =
            ServiceHelper.getRepository()
                .getVideoState("${videoHost}/httpflv.rctr.switch.${item.uuid}.$stream")
                .subscribe({
                    val result = GsonUtil.formObject<VideoState>(it)
                    if (result.state == "0") {
                        item.videoStream = stream
                    }
                }, {
                    MLog.e(" 切换码流失败")
                })
        netMap[item.videoPass] = subscribe
    }

    fun clearPlayer() {
        data.forEach {
            if (it.uuid.isNotEmpty())
                changeStreamOrClose(it, null, RealType.CLOSE)
        }
        data.clear()
        playerMap.clear()
    }

    fun destroy() {
        netMap.forEach {
            it.value.dispose()
        }
        netMap.clear()
    }

    fun getFullKey() = fullKey


}

enum class RealType {
    PLAY, CLOSE, SWITCH, STATE
}